<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>限高分析</title>
    <link rel="stylesheet" href="./lib/highLightStyles.css" />

    <script type="text/javascript" src="./lib/aircity/ac_conf.js"></script>
    <script type="text/javascript" src="./lib/aircity/ac.min.js"></script>
    <script type="text/javascript" src="./lib/Vue3.js"></script>
    <script type="text/javascript" src="./lib/ElementPlus/index.js"></script>
    <link rel="stylesheet" href="./lib/ElementPlus/index.css" />
  </head>
  <body>
    <div id="app">
      <div id="player" style="height: 100%"></div>
      <div class="control">
        <div class="top">
          <div>限高分析</div>
        </div>
        <div class="params">
          <div class="button-box">
            <button @click="start()">开始限高分析</button>
          </div>

          <div class="button-box">
            <button @click="stop()" class="sunlight stop">停止限高分析</button>
          </div>

          <div class="title">参数设置</div>
          <div class="item">
            <div class="label">
              <div>限制高度</div>
              <div style="color: #b6b6cf">({{ elevation }}m)</div>
            </div>
            <div class="content">
              <div class="range">
                <input
                  class="range11"
                  type="range"
                  v-model="elevation"
                  :min="0"
                  :max="300"
                />
              </div>
            </div>
          </div>

          <div class="item">
            <div class="label">超出颜色</div>
            <div class="content">
              <input type="color" v-model="color" style="width: 100%" />
            </div>
          </div>
          <div class="item">
            <div class="label">不透明度</div>
            <div class="content">
              <input
                type="number"
                v-model="opacity"
                style="width: 100%"
                :min="0"
                :max="1"
                :step="0.1"
              />
            </div>
          </div>
          <div class="item">
            <div class="label">限高面</div>
            <div class="content">
              <input type="checkbox" v-model="areaShow" />是否显示限高面
            </div>
          </div>
        </div>
      </div>
    </div>

    <script type="text/javascript">
      // 按需获取
      const { createApp, watch, ref } = Vue
      // 高度
      const elevation = ref(0)

      // 颜色
      const color = ref('#ff0000')

      // 透明度
      const opacity = ref(0.4)

      // 限高面是否显示
      const areaShow = ref(true)

      // 边界坐标
      let areaCoordinates = [
        [3731.0975, 5111.4817578125, 23.4746875],
        [3548.4500000000003, 4336.776640625, 30.0225],
        [3442.8, 3724.521015625, 29.4153125],
        [3339.9075000000003, 3278.25578125, 30.5125],
        [3449.185625, 2690.1371875, 16.5615625],
        [3494.899375, 2282.8815625, 13.7303125],
        [3579.4321875, 2009.6628125, 7.424375],
        [3603.2653125, 1984.7775000000001, 6.895078125],
        [3678.185, 2019.589375, 7.35890625],
        [3771.000625, 2079.5428125, 8.658515625],
        [3846.100625, 2121.3409375, 9.2928125],
        [3929.9065625000003, 2160.13375, 9.88875],
        [4091.6728125, 2196.9190625, 10.31796875],
        [4231.474375, 2197.95625, 10.49734375],
        [4276.2775, 2175.4915625, 10.29640625],
        [4412.925, 2101.4525, 9.4484375],
        [4629.02, 2087.764375, 8.096875],
        [4800.666875, 2018.175, 4.9710937500000005],
        [5013.11625, 1941.0290625, 0.62390625],
        [5155.271875, 1846.874375, -2.296796875],
        [5296.3440625, 1759.204375, -4.188046875],
        [5391.384375000001, 1674.7846875, -5.265390625],
        [5431.7990625, 1646.039375, -5.555390625],
        [5520.3790625, 1609.1365625, -6.278515625],
        [5589.0365625, 1605.1321875, -6.6015625],
        [5715.3462500000005, 1647.830625, -6.681328125],
        [5793.59515625, 1690.0934375, -4.83671875],
        [5881.803125, 1759.3656250000001, -5.932265625],
        [5976.24609375, 1876.10875, -4.6571875],
        [6171.4126562500005, 2113.3678125, -1.54546875],
        [6231.77, 2182.1953125, -0.65375],
        [6301.0265625, 2316.8490625, 0.810078125],
        [6370.58921875, 2411.14734375, 1.764921875],
        [6468.1746875, 2492.8040625, 2.679296875],
        [6595.993125, 2638.11265625, 3.914140625],
        [6892.42515625, 2844.69640625, 4.0240625],
        [7026.00171875, 3013.72484375, 2.5209375],
        [7425.5603125, 3334.225625, 0.31203125],
        [7655.841484375, 3666.531640625, 2.9992187500000003],
        [7796.6421484375005, 3787.5778906250002, 9.09875],
        [8018.006523437501, 4270.347265625, 3.5881250000000002],
        [8169.78541015625, 4668.83890625, 3.9245312500000002],
        [8278.36400390625, 5097.51640625, 3.9250000000000003],
        [8393.9155078125, 5516.56609375, 3.10828125],
        [8603.02802734375, 5838.47453125, 4.19921875],
        [8942.3378125, 6077.2837500000005, 4.1990625],
        [9098.16234375, 6107.357421875, 6.31640625],
        [8976.986171875, 6396.545625, 2.99890625],
        [8853.1554296875, 6593.9243750000005, 2.9987500000000002],
        [8725.20734375, 6782.40203125, 3.00125],
        [8438.0246875, 6998.4065625, 42.8459375],
        [8465.816328125, 7110.69703125, 2.9990625],
        [8491.94859375, 7300.7596875, 2.9978125],
        [8477.0208984375, 7352.81046875, 2.9991015625],
        [8390.360546875, 7314.64421875, 2.5299609375],
        [8249.503828125, 7586.71, 2.5295312500000002],
        [8090.6128125000005, 7952.980625, 17.65953125],
        [7477.891953125, 7548.5734375, 2.5328125],
        [6513.23625, 7109.52453125, 44.4934375],
        [5699.21875, 6684.43640625, 45.3203125],
        [4890.5, 6190.61375, 57.805625],
        [4578.7009375, 5854.611796875, 45.736875],
        [4219.7490625, 5473.845625, 25.306562500000002],
        [3919.56625, 5233.55453125, 20.4796875]
      ]

      /**
       * 开始限高分析
       */
      const start = () => {
        // 用于判断当前是否有图层，没有就加载，有就直接调用
        if (!areaCoordinates) {
          // 用于限高的范围
          fetch('/data/border.geojson')
            .then(response => {
              return response.json()
            })
            .then(data => {
              areaCoordinates = data.features[0].geometry.coordinates[0][0]
              start()
            })
        } else {
          addHighlight()
          if (areaShow.value) addArea()
        }
      }

      /**
       * 添加高亮图层
       */
      const addHighlight = () => {
        // y轴高度
        const y = Number(elevation.value)

        // 操作对象
        let areaObj = {
          id: 'highlight', //湖水的id
          coordinates: areaCoordinates, //构成湖水区块的数据
          color: toColorArr(color.value, opacity.value),
          intensity: 2,
          heightRange: [y, 1000]
        }

        // 添加高亮面
        __g.highlightArea.add(areaObj, null)
      }

      /**
       * 添加限高面
       */
      const addArea = () => {
        const y = Number(elevation.value)

        areaCoordinates.forEach(item => {
          item[2] = y
        })
        __g.polygon.add(
          {
            id: 'polygon', //polygon唯一标识id
            coordinates: areaCoordinates, //构成polygon的坐标点数组
            range: [1, 10000], //可视范围：[近裁距离, 远裁距离]，取值范围: [任意负值, 任意正值]
            color: [1, 1, 0, 0.5], //polygon颜色
            frameThickness: 1, //边框厚度
            intensity: 1, //亮度
            style: 0, // 请参照API开发文档选取枚举
            depthTest: true //是否做深度检测
          },
          null
        )
      }

      /**
       * 限高分析高度更新
       */
      const update = () => {
        // y轴高度
        const y = Number(elevation.value)
        let areaObj = {
          id: 'highlight', //湖水的id
          coordinates: areaCoordinates, //构成湖水区块的数据
          color: toColorArr(color.value, opacity.value),
          intensity: 2,
          heightRange: [y, 1000]
        }
        // 更新水面
        __g.highlightArea.update(areaObj, null)

        if (areaShow.value) {
          areaCoordinates.forEach(item => {
            item[2] = y
          })
          // 更新面
          __g.polygon.update(
            {
              id: 'polygon', //polygon唯一标识id
              coordinates: areaCoordinates, //构成polygon的坐标点数组
              range: [1, 10000], //可视范围：[近裁距离, 远裁距离]，取值范围: [任意负值, 任意正值]
              color: [1, 1, 0, 0.5], //polygon颜色
              frameThickness: 1, //边框厚度
              intensity: 1, //亮度
              style: 0, // 请参照API开发文档选取枚举
              depthTest: true //是否做深度检测
            },
            null
          )
        }
      }

      // elevation监听，开启更新事件
      watch(elevation, () => {
        update()
      })

      // color监听，开启更新事件
      watch(color, () => {
        update()
      })

      // opacity监听，开启更新事件
      watch(opacity, () => {
        update()
      })

      // areaShow监听，开启更新事件
      watch(areaShow, val => {
        if (val) {
          addArea()
        } else {
          __g.polygon.clear()
        }
      })

      /**
       * 停止限高分析
       */
      const stop = () => {
        // 删除高亮图层
        __g.highlightArea.clear()
        // 删除面图层
        __g.polygon.clear()
      }

      /**
       * 16进制颜色转[1,0,0,0]，附上透明度
       * @param sColor 16进制颜色
       * @param opacity 透明度
       * @returns {*[]|*}
       */
      const toColorArr = (sColor, opacity) => {
        const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
        if (sColor && reg.test(sColor)) {
          if (sColor.length === 4) {
            var sColorNew = '#'
            for (var i = 1; i < 4; i += 1) {
              sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
            }
            sColor = sColorNew
          }
          //处理六位的颜色值
          var sColorChange = []
          for (var i = 1; i < 7; i += 2) {
            sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)) / 255)
          }
          sColorChange.push(opacity)
          return sColorChange
        } else {
          return sColor
        }
      }

      /**
       * 初始化三维
       * @constructor
       */
      const OnLoad = () => {
        const __DigitalTwinPlayer = new DigitalTwinPlayer(HostConfig.Player, {
          domId: 'player',
          apiOptions: {
            onReady: function () {
              fdapi.reset(1 | 2 | 4)
              __g.weather.setDateTime(2023, 6, 25, 8, 35, false)
              __g.camera.set([
                10054.157656, 3945.6125, 1342.177344, -14.927931, -167.37854, 1
              ])
            }
          }
        })
      }
      /**
       * 自适应分辨率
       * @returns {Promise<void>}
       */
      const onResize = async () => {
        let playerView = document.getElementById('player')
        playerView.style.height = window.innerHeight + 'px'
        playerView.style.width = window.innerWidth + 'px'
      }
      // vue挂载
      const app = createApp({
        setup() {
          // 页面加载调用
          window.addEventListener('load', OnLoad, true)
          // 页面窗口变换调用
          window.addEventListener('resize', onResize, true)
          //页面离开事件(离开时清除此页面的操作及重置场景)
          window.onunload = function (e) {
            // 重置场景
            fdapi.reset(1 | 2 | 4)
          }
          return {
            elevation,
            color,
            opacity,
            areaShow,
            start,
            stop
          }
        }
      })
      app.use(ElementPlus).mount('#app')
    </script>
  </body>
</html>
